#include "Temp.h";

extern LiquidCrystal lcd;
extern DallasTemperature sensors;

prog_char temp_probe_name_0[] PROGMEM = "Aquarium Temp";
prog_char temp_probe_name_1[] PROGMEM = "Water Change Temp";
prog_char temp_probe_name_2[] PROGMEM = "Aquarium Probe";
prog_char temp_probe_name_3[] PROGMEM = "Water Change Probe";
prog_char temp_probe_name_4[] PROGMEM = "Aquarium";
prog_char temp_probe_name_5[] PROGMEM = "Change";

 
PROGMEM const char *temp_probes_name_table[] = 
{   
  temp_probe_name_0,
  temp_probe_name_1,
  temp_probe_name_2,
  temp_probe_name_3,
  temp_probe_name_4,
  temp_probe_name_5
};

DeviceAddress AQUARIUM_PROBE_ADDRESS = {0x28,0xF6,0xD6,0x4B,0x3,0x0,0x0,0x8C}; 
DeviceAddress WATER_CHANGE_PROBE_ADDRESS = {0x28,0x14,0xAF,0x7A,0x3,0x0,0x0,0x92}; 
DeviceAddress *PROBES_ADDRESS[TEMP_NUMBER_OF_PROBES] = { &AQUARIUM_PROBE_ADDRESS , &WATER_CHANGE_PROBE_ADDRESS };

void Temp::init(){
  int address = EEPROM_TEMP_ADDRESS_START;
  for (int i = 0 ; i < TEMP_NUMBER_OF_PROBES ; ++ i ){
    temp_calibration_b[i] = EEPROM.read(address++) ;
    temp_calibration[ i ] =  get_calibration(    temp_calibration_b[i]  );
  }

  for (int i = 0 ; i < TEMP_NUMBER_OF_PROBES ; ++ i ){
    temp[i] = 25.5;
  }
  
  
  sensors.begin();
  lcd.setCursor(0, 2);
  lcd.print("Found ");
  int DeviceCount =  sensors.getDeviceCount();
  lcd.print(DeviceCount, DEC);
  lcd.print(" devices.");
  
   for(int i = 0 ; i <  TEMP_NUMBER_OF_PROBES ; ++i){
       ProbeFound[i] = false;
   }

  
  for(int i = 0 ; i <  DeviceCount ; ++i){
     DeviceAddress address;
     sensors.getAddress(address, i);  
     sensors.setResolution(address,11);
     
     for(int probe = 0 ; probe <  TEMP_NUMBER_OF_PROBES ; ++probe){
       bool found = true;
       if( ProbeFound[probe] == false ){
         for (uint8_t j = 0; j < 8; ++j)  {
          if(address[j] != (*(PROBES_ADDRESS[probe]))[j] )
           found=false;
         }
         ProbeFound[probe] = found;
       }
     }
   }
  
  for(int probe_num = 0 ; probe_num <  TEMP_NUMBER_OF_PROBES ; ++probe_num){
     if( ProbeFound[probe_num] ){
       delay(1000);
      lcd.clear();
      lcd.setCursor(0, 1);
      strcpy_P(buffer, (char*)pgm_read_word(&(  temp_probes_name_table[ probe_num+TEMP_NUMBER_OF_PROBES ]     )));
      lcd.print(buffer );
      lcd.setCursor(0, 2);
      lcd.print("Found");
    }
  }
  
  sensors.setWaitForConversion(false);  // makes it async
  sensors.requestTemperatures();
  /*
  for(int i = 0 ; i <  DeviceCount ; ++i){
    
    DeviceAddress insideThermometer;
    lcd.clear();
    sensors.getAddress(insideThermometer, i);
    lcd.setCursor(0, 2);
    lcd.print("Device Address: ");
    lcd.setCursor(0, 3);
    for (uint8_t i = 0; i < 8; i++)  {
      if (i > 0) lcd.print(",");
      lcd.print(insideThermometer[i], HEX);
    }
    delay(10000);
  }
  */
  
}

void Temp::update_temp(){
  for(int i = 0 ; i <  TEMP_NUMBER_OF_PROBES ; ++i){
      if(ProbeFound[i]){
        temp[i] = sensors.getTempC((*(PROBES_ADDRESS[i])));
      }  
  }
  sensors.requestTemperatures(); // Send the command to get temperatures   
}

float Temp::get_temp(byte probe_num){
  return temp[ probe_num ] + temp_calibration[ probe_num ];
}

char Temp::get_temp_calibration(byte probe_num){
  return temp_calibration_b[ probe_num ];
}

void Temp::set_temp_calibration(byte probe_num,char calibration){
  int address = EEPROM_TEMP_ADDRESS_START+probe_num;
  temp_calibration_b[ probe_num ] = calibration;
  temp_calibration[ probe_num ] =  get_calibration(calibration);
  EEPROM.write(address, calibration) ;
}

void Temp::print_temp(byte probe_num){
  lcd.print(temp[ probe_num ] + temp_calibration[ probe_num ] );
  lcd.print( (char) 223 );
  lcd.print( "C" );
}

float Temp::get_calibration(char calibration){
  return ( (float)calibration ) / 10;   
}

void Temp::print_temp(byte probe_num,char calibration){
  lcd.print(temp[ probe_num ] +  get_calibration(calibration)  ) ;
  lcd.print( (char) 223 );
  lcd.print( "C" );
}

void Temp::print_temp_without_calibration(byte probe_num){
  lcd.print(temp[ probe_num ] );
  lcd.print( (char) 223 );
  lcd.print( "C" );
}

void Temp::print_temp_calibration(byte probe_num){
  lcd.print(temp_calibration[ probe_num ] );
  lcd.print( (char) 223 );
  lcd.print( "C" );
}

void Temp::print_probe_name(byte probe_num){
  strcpy_P(buffer, (char*)pgm_read_word(&(  temp_probes_name_table[ probe_num ]     )));
  lcd.print(buffer );
}

void Temp::print_probe_name_sort(byte probe_num){
  strcpy_P(buffer, (char*)pgm_read_word(&(  temp_probes_name_table[ probe_num + TEMP_NUMBER_OF_PROBES*2 ]     )));
  lcd.print(buffer );
}



float Temp::get_temp(byte temp_h,byte temp_l){
  float temp = temp_l;
  temp = temp / 100;
  temp+=  temp_h;
  return temp;
}

void Temp::print_temp(float temp){
  if(temp < 10){
    lcd.print( " " );
  }
  lcd.print(temp);
  lcd.print( (char) 223 );
  lcd.print( "C" );
}

void Temp::print_temp(byte temp_h , byte temp_l){
  float temp = get_temp(temp_h,temp_l);
  print_temp(temp);
}











